import React, { useEffect, useMemo, useState } from 'react';
import { Drawer, Empty, message, Select, Statistic, Switch } from 'antd';
import moment from 'moment';

import apiConfig from '@/api/config';
import { api } from '@/api/index';
import { API_RESULT, MENU_KEY, SYS_TAG, TASK_STATUS } from '@/const';
import ContentList from '@/components/ContentList';
import ToolBar from '@/components/Toolbar';
import TButton from '@/components/TButton';
import PageTitle from '@/components/PageTitle';
import DivideLine from '@/components/Divider';
import QuickCreator from '@/components/QuickCreator';
import DeleteWrapper from '@/components/DeleteWrapper';

import TaskItem from './components/TaskItem';

import './index.less';
import { useDatabase } from '@/hooks/useDatabase';

const { Option, OptGroup } = Select;

export type TaskT = {
  id: string;
  title: string;
  desc: string;
  startTime: moment.Moment;
  endTime: moment.Moment;
  finishTime: moment.Moment | '';
  status: number;
  tags: string[];
};

type StatisticsT = {
  todaysRemain: number;
  outdated: number;
  todaysFinished: number;
  allFinished: number;
  allRemain: number;
  waitToStart: number;
};

interface IProps {
  onCountChange: (count: number) => void;
}

const RESTORE_TASK_LOCAL_KEY = 'todo-task-restore';

const DB_CONFIG = {
  init: true,
  getUrl: apiConfig.getTodo.url,
  restoreKey: RESTORE_TASK_LOCAL_KEY,
  createUrl: apiConfig.createTodo.url,
  removeUrl: apiConfig.removeTodo.url,
  updateUrl: apiConfig.updateTodo.url,
  dataMapper: (i: TaskT) => {
    return Object.assign(i, {
      endTime: moment(i.endTime),
      startTime: moment(i.startTime),
      finishTime: i.finishTime ? moment(i.finishTime) : '',
      tags: i.tags ? i.tags : [],
    });
  },
};

export default function TaskList(props: IProps) {
  const { onCountChange } = props;

  const [filter, setFilter] = useState('');
  const [selectTags, setSelectTags] = useState<string[]>([]);

  const [activeKey, setActiveKey] = useState(MENU_KEY.TASK); // 0-1区分两类任务列表

  const {
    data: tasks = [],
    activeTarget,
    setActiveTarget,
    create,
    remove,
    update,
  } = useDatabase<TaskT>({
    getDep: [activeKey],
    getParams: () => ({ type: activeKey }),
    ...DB_CONFIG,
  });

  const [showStatistics, setShowStatistics] = useState(false);
  const [statistics, setStatistics] = useState<StatisticsT>({
    todaysRemain: 0,
    outdated: 0,
    todaysFinished: 0,
    allFinished: 0,
    allRemain: 0,
    waitToStart: 0,
  });

  // 右上方搜索栏根据任务名称筛选出的任务
  const filteredTasks = useMemo<TaskT[]>(() => {
    if (filter) {
      return tasks.filter((i) => i.title.includes(filter));
    } else {
      return tasks;
    }
  }, [tasks, filter]);

  const classifiedTasks = useMemo(() => {
    if (selectTags.length === 0) {
      return filteredTasks;
    }

    return filteredTasks.filter((i) => {
      // 判断自定义标签是否在当前筛选标签内
      for (const t of i.tags) {
        if (selectTags.includes(t)) {
          return true;
        }
      }
      // 判断系统默认标签（时间计算类）是否在当前筛选标签内
      const today = moment(new Date().toISOString().split('T')[0]);
      const endTime = moment(i.endTime.toISOString().split('T')[0]);
      const startTime = moment(i.startTime.toISOString().split('T')[0]);
      if (
        selectTags.includes(SYS_TAG.TODAY) &&
        startTime.isSameOrBefore(today) &&
        endTime.isSameOrAfter(today)
      ) {
        return true;
      }
      if (selectTags.includes(SYS_TAG.TODAY_DDL) && endTime.isSame(today)) {
        return true;
      }
      if (selectTags.includes(SYS_TAG.NOT_START) && startTime.isAfter(today)) {
        return true;
      }
      if (selectTags.includes(SYS_TAG.OVERTIME) && endTime.isBefore(today)) {
        return true;
      }
      return false;
    });
  }, [filteredTasks, selectTags]);

  const allTags = useMemo(() => {
    return [...new Set(tasks.map((i) => i.tags).flat())];
  }, [tasks]);

  useEffect(() => {
    initData();
  }, []);

  useEffect(() => {
    onCountChange?.(tasks.length);
  }, [tasks.length]);

  const initData = () => {
    api(apiConfig.todoStatistics.url).then((res) => {
      if (res.code === API_RESULT.SUCCESS) {
        setStatistics(res.data);
      }
    });
  };

  const handleCreate = (v: any) => {
    create({
      title: v.title,
      startTime: moment(),
      endTime: v.endTime,
      desc: '',
      id: Date.now().toString(),
      status: TASK_STATUS.DOING,
      finishTime: '',
      tags: [],
    })
      .then(() => {
        message.success('创建成功！');
      })
      .catch((e) => {
        message.error('创建失败');
      });
  };

  const handleRemove = (task: TaskT) => {
    remove(task)
      .then(() => {
        message.success('移除成功！');
      })
      .catch((e) => {
        console.error('移除失败', e);
      });
  };

  const handleUpdate = (item: TaskT) => {
    update(item)
      .then(() => {
        message.success('已更新');
      })
      .catch((e) => {
        message.error('更新失败');
      });
  };

  const handleFinish = (id: string) => {
    const finishedTask = tasks.find((i) => i.id === id);
    handleUpdate(
      Object.assign({}, finishedTask, {
        status:
          activeKey === MENU_KEY.TASK ? TASK_STATUS.DONE : TASK_STATUS.DOING,
        finishTime: activeKey === MENU_KEY.TASK ? moment() : '',
      }),
    );
  };

  const renderContent = () => {
    if (!activeTarget) {
      return <></>;
    }
    const i = activeTarget;
    const { endTime, startTime, finishTime } = activeTarget;

    return (
      <>
        <PageTitle
          title={activeTarget.title}
          subTitle={
            <div className="task-item__detail">
              <div className="container">
                <label>开始时间</label>
                <div className="task-item__ddl tag">
                  {startTime.format('Y-M-D HH:mm')}
                </div>
              </div>
              <div className="container">
                <label>截止时间</label>
                <div className="task-item__ddl tag">
                  {endTime.format('Y-M-D HH:mm')}
                </div>
              </div>

              {finishTime !== '' && (
                <div className="container">
                  <label>完成时间</label>
                  <div className="task-item__ddl tag">
                    {finishTime.format('Y-M-D HH:mm')}
                  </div>
                </div>
              )}

              {endTime.diff(moment()) < 0 && (
                <div className="container">
                  <label>截止状态</label>
                  <div className="task-item__timeout tag">{`${endTime.fromNow()}已截止`}</div>
                </div>
              )}
            </div>
          }
        />
        <TaskItem
          task={i}
          tagList={allTags}
          key={i.id}
          onSubmit={handleUpdate}
        />
      </>
    );
  };

  const renderListItem = (task: TaskT) => {
    return (
      <div className="task-content-list-item">
        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
          <DeleteWrapper
            onRemove={() => {
              handleRemove(task);
            }}
          >
            <div className="task-content-list-item__delete">
              <span></span>
            </div>
          </DeleteWrapper>
          <span
            className={`task-content-list-item__title${
              task.endTime.diff(moment()) < 0 ? '--timeout' : ''
            }`}
          >
            {task.title}
          </span>

          <TButton onClick={() => handleFinish(task.id)}>
            {task.status === TASK_STATUS.DOING ? '完成' : '重启'}
          </TButton>
        </div>
        <span className="task-content-list-item__desc">
          {task.endTime.fromNow()}截止
        </span>
      </div>
    );
  };

  const renderMain = () => {
    if (!tasks.length) {
      return (
        <Empty
          description={
            activeKey === MENU_KEY.TASK
              ? '暂无进行中的任务哦'
              : '还没有完成过任务哦'
          }
        />
      );
    }
    return (
      <div className="task-list">
        <ContentList
          list={classifiedTasks}
          activeKey={activeTarget?.id || ''}
          keyField="id"
          onSelect={(key) => {
            const item =
              classifiedTasks.find((i) => i.id === key) || classifiedTasks?.[0];
            setActiveTarget(item);
          }}
          content={renderContent()}
          listRender={renderListItem}
          tools={['search']}
          searchKey="title"
          onSearch={(v) => setFilter(v)}
          sorter={(a: TaskT, b: TaskT) => {
            if (activeKey === 0) {
              // 按照截止时间，越早越前
              return a.endTime.diff(b.endTime);
            } else {
              // 对于已完成的任务，越晚（新）完成越前
              if (a.finishTime === '' || b.finishTime === '') {
                return 0;
              }
              return b.finishTime.diff(a.finishTime);
            }
          }}
        />
      </div>
    );
  };

  const renderTagSelector = () => {
    return (
      <div className="container">
        <Switch
          checked={activeKey === 0}
          checkedChildren="进行中"
          unCheckedChildren="已完成"
          onChange={(checked) => setActiveKey(checked ? 0 : 1)}
          style={{ margin: '0 4px', minWidth: '70px' }}
        />
        <div className="standard-container">
          <Select
            mode="multiple"
            style={{ width: '200px', marginRight: '4px' }}
            size="small"
            placeholder="标签筛选"
            value={selectTags}
            onChange={(v) => {
              setSelectTags(v);
            }}
          >
            <OptGroup label="默认标签">
              {Object.values(SYS_TAG).map((i) => (
                <Option key={i} value={i}>
                  {i}
                </Option>
              ))}
            </OptGroup>
            <OptGroup label="自定义标签">
              {allTags.map((i) => (
                <Option key={i} value={i}>
                  {i}
                </Option>
              ))}
            </OptGroup>
          </Select>
        </div>
      </div>
    );
  };

  const renderRightActions = () => {
    return (
      <>
        {renderTagSelector()}
        <TButton
          onClick={() => setShowStatistics(true)}
          plain
          style={{ marginLeft: '10px' }}
        >
          统计
        </TButton>
      </>
    );
  };

  const renderStatistics = () => {
    const entries = Object.entries(statistics) as [keyof StatisticsT, number][];
    const names = {
      todaysRemain: '今日截止',
      outdated: '已超时',
      todaysFinished: '今日完成',
      allFinished: '总共完成',
      allRemain: '今日进行',
      waitToStart: '待开始',
    } as Record<keyof StatisticsT, string>;

    return (
      <Drawer
        title="统计"
        placement="right"
        onClose={() => setShowStatistics(false)}
        visible={showStatistics}
      >
        {entries.map((e) => (
          <React.Fragment key={e[0]}>
            <Statistic title={names[e[0]]} value={e[1]} key={e[0]} />
            <DivideLine bottom={10} />
          </React.Fragment>
        ))}
      </Drawer>
    );
  };

  return (
    <>
      <ToolBar
        leftActions={
          <QuickCreator
            defaultFields={{
              startTime: moment(),
              endTime: moment().add(1, 'day'),
            }}
            mainField="title"
            onCreate={handleCreate}
            placeholder="回车快速创建待办任务"
          />
        }
        rightActions={renderRightActions()}
      />
      {renderMain()}
      {renderStatistics()}
    </>
  );
}
